/*
  The MIT License
  
  Copyright (c) 2009 smath project
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
package pl.smath.expression.parser.text;

import junit.framework.TestCase;
import pl.smath.expression.model.BooleanTerm;
import pl.smath.expression.model.DisjunctionTerm;
import pl.smath.expression.model.NumberTerm;
import pl.smath.expression.model.ProductTerm;
import pl.smath.expression.model.Term;
import pl.smath.expression.parser.ExpressionParser;
import pl.smath.expression.parser.ExpressionParserException;


public class ParserTestCase extends TestCase {

	/** 
	 * Zbiór podstawowych przykładów testowych
	 */
	private static final String[] TEST_DATA1 = {
		"2",
		"x",
		"-12.9",
		"-x",
		"2*3",
		"4/2",
		"8/4/2",
		"2+3",
		"2-3",
		"2*3-12",
		"2-12*2",
		"3+x",
		"x+x+x",
		"x-x-x",
		"x-(x-x)",
		"x+(x-x)",
		"x-(-x-x)",
		"(x+2)/(x-x)",
		"x^y",
		"(x^y)^z",
		"3*x^2+2*x^2",
		"x^4+3*x^3+x^2-x-(x^3-2*x^2-x)",
		"(x+2)*(x+3)-5*(x-2)",
		"(3*x)^2+(2*x)^a",
		"(a/b)^2",
		"1.5*3.2",
		"x+3+(x+5)",
		"2^(1+2)",
		"(3*x)/(2*x+x)",
		"(3*x)/x",
		"4$2",
		"(x+1)$(x-y)",
		"a=x",
		"-(x+1)$(x-y)=x+3+(x+5)",
		"5^(3/2)",
		"4!=3",
		"4>=3",
		"4>3",
		"a<b",
		"2*a<=3+b",
		"-2*a/b*x",
		"2*a/b*-x",
		"((7*a)$2+(2*b)$2)*((7*a)$2-(2*b)$2)",
		"{2, x}",
		"|x|",
		"x \\wedge y \\wedge z",
		"x \\vee y \\vee z",
		"(x \\vee y) \\wedge (x \\vee y)",
		"(TRUE \\vee FALSE) \\wedge (FALSE \\vee FALSE)",
		"4:2",
		"x \\in A",
	};
	
	/**
	 * Gdy odpowiedz renderuje sie inaczej niz wejscie
	 */
	private static final String[][] TEST_DATA2 = {
		{"3--4", "3+4"},
		{"2x", "2*x"},
		{"2x(x+3y)", "2*x*(x+3*y)"},
		{"\\sqrt{x}", "x$2"},
		{"\\sqrt[3]{x}", "x$3"},
		{"\\frac{x}{y}", "x/y"},
	};
	
	
	public void testData1() throws ExpressionParserException {
		Term expression;
		TextParser parser = new TextParser();
		
		for(int i = 0; i < TEST_DATA1.length; i++){
			
			expression = parser.parse( TEST_DATA1[i] );
			assertNotNull(TEST_DATA1[i], expression);
			assertEquals(TEST_DATA1[i], expression.toString());
		}
	}
	
	
	public void testData2() throws ExpressionParserException {
		Term expression;
		TextParser parser = new TextParser();
		
		for(int i = 0; i < TEST_DATA2.length; i++){

			expression = parser.parse( TEST_DATA2[i][0] );
			assertNotNull(TEST_DATA2[i][0], expression);
			assertEquals(TEST_DATA2[i][1], expression.toString());
		}
	}
	
	
	/**
	 * Sprawdzenie jak sie zachowa parser przy wpisaniu wielu minusow
	 */
	public void testMinusPower()  throws ExpressionParserException{
		Term expression;
		ExpressionParser parser = new ExpressionParser();
		
		expression = parser.parseText( "-x^2" );
		assertTrue(expression.isNegative());
		
	}
	
	/**
	 */
	public void testProductType()  throws ExpressionParserException{
		Term expression;
		ExpressionParser parser = new ExpressionParser();
		
		expression = parser.parseText( "3*4/2" );
		assertTrue(expression instanceof ProductTerm);
		
	}
	
	/**
	 */
	public void testProductType2()  throws ExpressionParserException{
		Term expression;
		ExpressionParser parser = new ExpressionParser();
		
		expression = parser.parseText( "x/x*x" );
		assertTrue(expression instanceof ProductTerm);
		
	}
	
	/**
	 */
	public void testProductType3()  throws ExpressionParserException{
		Term expression;
		ExpressionParser parser = new ExpressionParser();
		
		expression = parser.parseText( "a*(-1)" );

		assertTrue(expression instanceof ProductTerm);
		
		Term term = ((ProductTerm)expression).getTerms().get(1);
		assertTrue(term instanceof NumberTerm);
		assertTrue(term.isNegative());
		
	}
	
	/**
	 */
	public void testProductType4()  throws ExpressionParserException{
		Term expression;
		ExpressionParser parser = new ExpressionParser();
		
		expression = parser.parseText( "-a*b" );

		assertTrue(expression instanceof ProductTerm);
		
		assertTrue(expression.isNegative());
		
	}
	
	/**
	 */
	public void testBoolean()  throws ExpressionParserException{
		
		ExpressionParser parser = new ExpressionParser();
		BooleanTerm term;
		
		DisjunctionTerm expression = (DisjunctionTerm)parser.parseText( "TRUE \\vee FALSE" );

		assertEquals(2, expression.getTerms().size());
		
		assertTrue(expression.getTerms().get(0) instanceof BooleanTerm);
		assertTrue(expression.getTerms().get(1) instanceof BooleanTerm);
		
		term = (BooleanTerm) expression.getTerms().get(0);
		assertTrue(term.getValue());
		
		term = (BooleanTerm) expression.getTerms().get(1);
		assertFalse(term.getValue());
		
	}
	
}
